export class HashMap<T>{
    private _values: Array<T>;
    private _keys: Array<string | number>;
    protected _cls: any;		//有些地方需要class壳处理逻辑
    constructor(cls?: any) {
        this._values = [];
        this._keys = [];
        this._cls = cls;
    }

    protected _installT(d: T): T {
        if (this._cls) {
            var newD = new this._cls();
            lowCpData(newD, d);
            return newD;
        }
        return d;
    }


    /**
     * 增加对象
     * @param key 
     * @param val 
     * @return 增加返回true，更新返回false
     */
    public add(key: string | number, val: T) {
        var index = this._keys.indexOf(key);
        if (index == -1) {
            this._keys.push(key);
            this._values.push(this._installT(val));
            return true;
        } else {
            if (this._cls) {
                lowCpData(this._values[index], val);
            } else {
                this._values[index] = val;
            }
            return false;
        }
    }

    public get(key: string | number): T {
        var index = this._keys.indexOf(key);
        if (index == -1) {
            return null
        }
        return this._values[index];
    }

    public del(key: string | number): T {
        var index = this._keys.indexOf(key);
        if (index == -1) {
            return null
        }
        this._keys.splice(index, 1);
        return this._values.splice(index, 1)[0]
    }


    public has(key: string | number): boolean {
        return this._keys.indexOf(key) != -1;
    }

    public get length(): number {
        return this._keys.length;
    }

    public get values(): Array<T> {
        return this._values.concat();
    }

    public get keys(): Array<string | number> {
        return this._keys.concat();
    }

    public dispose() {
        this._values = null;
        this._keys = null;
    }
}

/**简单的浅层拷贝 chkTargetKey判断是否要考虑目标的key是否存在 */
export function lowCpData(target: any, data: any, chkTargetKey: boolean = false) {
    for (var key in data) {
        if (data.hasOwnProperty(key)) {
            var element = data[key];
            if (element == null) continue;
            if ((chkTargetKey && target.hasOwnProperty(key)) || !chkTargetKey) {
                target[key] = element;
            }
        }
    }
}